package com.liangxy.zhyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.liangxy.zhyl.constant.SuperConstant;
import com.liangxy.zhyl.dto.ResourceDto;
import com.liangxy.zhyl.entity.Resource;
import com.liangxy.zhyl.enums.BasicEnum;
import com.liangxy.zhyl.exception.BaseException;
import com.liangxy.zhyl.mapper.ResourceMapper;
import com.liangxy.zhyl.service.ResourceService;
import com.liangxy.zhyl.utils.EmptyUtil;
import com.liangxy.zhyl.utils.NoProcessing;
import com.liangxy.zhyl.utils.StringUtils;
import com.liangxy.zhyl.vo.ResourceVo;
import com.liangxy.zhyl.vo.TreeItemVo;
import com.liangxy.zhyl.vo.TreeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ResourceServiceImpl implements ResourceService {

    @Autowired
    private ResourceMapper resourceMapper;
    /**
     * 多条件查询资源列表
     * @param resourceDto
     * @return
     */
    @Override
    public List<ResourceVo> findResourceList(ResourceDto resourceDto) {
        List<Resource> resourceList = resourceMapper.selectList(resourceDto);
        // 转换为VO集合
        return BeanUtil.copyToList(resourceList, ResourceVo.class);
    }

    /**
     * 树形结构
     * @param resourceDto
     * @return
     */
    @Override
    public TreeVo resourceTreeVo(ResourceDto resourceDto) {
        //构造查询条件
        ResourceDto dto = ResourceDto.builder()
                .dataState(SuperConstant.DATA_STATE_0) // 启用
                .parentResourceNo(NoProcessing.processString(SuperConstant.ROOT_PARENT_ID)) // 根节点
                .resourceType(SuperConstant.MENU).build(); // 菜单雷星的权限
        //查询所有资源数据
        List<Resource> resourceList = resourceMapper.selectList(dto);
        if(EmptyUtil.isNullOrEmpty(resourceList)){
            throw new RuntimeException("资源信息未定义");
        }
        //没有根节点，构建根节点
        Resource rootResource = new Resource();
        rootResource.setResourceNo(SuperConstant.ROOT_PARENT_ID);
        rootResource.setResourceName("桑榆情");

        //返回的树形集合
        List<TreeItemVo> itemVos = new ArrayList<>();

        //使用递归构建树形结构
        recursionTreeItem(itemVos,rootResource,resourceList);

        return TreeVo.builder().items(itemVos).build();
    }



    /**
     * 使用递归构建树形结构
     * @param itemVos // 空的，需要构建的集合
     * @param rootResource
     * @param resourceList
     */
    private void recursionTreeItem(List<TreeItemVo> itemVos, Resource rootResource, List<Resource> resourceList) {
        //构建每个资源的属性
        TreeItemVo treeItemVo = TreeItemVo.builder()
                .id(rootResource.getResourceNo())
                .label(rootResource.getResourceName()).build();
        //获取当前资源下的子资源
        List<Resource> childrenResourceList = resourceList.stream()
                .filter(n -> n.getParentResourceNo().equals(rootResource.getResourceNo()))
                .collect(Collectors.toList());
        //判断子资源是否为空
        if(!EmptyUtil.isNullOrEmpty(childrenResourceList)){
            List<TreeItemVo> listChildren = new ArrayList<>(); // 空的，需要构建的集合
            //构建子资源
            childrenResourceList.forEach(resource -> {
                recursionTreeItem(listChildren,resource,resourceList);
            });
            treeItemVo.setChildren(listChildren);
        }
        //为空，添加到集合
        itemVos.add(treeItemVo);
    }

    /**
     * 添加资源
     * @param resourceDto
     */
    @Override
    public void createResource(ResourceDto resourceDto) {
        //属性拷贝
        Resource resource = BeanUtil.toBean(resourceDto, Resource.class);
        //查询父资源
        Resource parentResource = resourceMapper.selectByResourceNo(resourceDto.getParentResourceNo());
        //子资源的状态与夫资源一致
        resource.setDataState(parentResource.getDataState());
        boolean isIgnore = true;
        //判断是否是按钮，如果是按钮，则不限制层级
        if(StringUtils.isNotEmpty(resourceDto.getResourceType())
            && resourceDto.getResourceType().equals(SuperConstant.BUTTON)){
            isIgnore = false;
        }
        //创建当前资源的编号，是菜单还是按钮，则限制层级
        String resourceNo = createResourceNo(resourceDto.getParentResourceNo(),isIgnore);
        resource.setResourceNo(resourceNo);
        resourceMapper.insert(resource);

    }

    /**
     * 创建资源编号
     * @param parentResourceNo
     * @param isIgnore
     * @return
     */
    private String createResourceNo(String parentResourceNo, boolean isIgnore) {
        //100 001 000 000 000
        //100 001 001 000 000
        //100 001 001 001 000
        //100 001 001 001 001 001
        //判断菜单类型的资源编号是否大于三级
        if(isIgnore && NoProcessing.processString(parentResourceNo).length() / 3 >= 5){
            throw new BaseException(BasicEnum.RESOURCE_DEPTH_UPPER_LIMIT);
        }
        //根据父资源编号查询子资源
        ResourceDto dto = ResourceDto.builder().parentResourceNo(parentResourceNo).build();
        List<Resource> resourceList = resourceMapper.selectList(dto);
        if(EmptyUtil.isNullOrEmpty(resourceList)){
            //无下属节点，创建新的节点编号
            //100 001 001 001 000 -->100 001 001 001 001
            return NoProcessing.createNo(parentResourceNo,false);
        }else{
            //有下属节点，在已有节点上追加
            //100 001 001 001 000 -->100 001 001 001 003 -->100 001 001 001 004
            //先获取已有节点的最大值
            Long maxNo = resourceList.stream()
                    .map(resource -> {
                        return Long.valueOf(resource.getResourceNo());
                    }).max(Comparator.comparing(i -> i)).get();
            return NoProcessing.createNo(String.valueOf(maxNo),true);
        }

    }

}
